package net.suncaper.mvc.service.impl;

import net.suncaper.mvc.exception.BusinessException;
import net.suncaper.mvc.mapper.OrderMapper;
import net.suncaper.mvc.mapper.RoomMapper;
import net.suncaper.mvc.mapper.impl.OrderMapperImpl;
import net.suncaper.mvc.mapper.impl.RoomMapperImpl;
import net.suncaper.mvc.model.domain.Message;
import net.suncaper.mvc.model.domain.Order;
import net.suncaper.mvc.model.domain.Room;
import net.suncaper.mvc.service.IMessageService;
import net.suncaper.mvc.service.IOrderService;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 订单业务接口实现类
 */
public class OrderServiceImpl implements IOrderService {
    private final OrderMapper orderMapper = new OrderMapperImpl();
    // 注入RoomMapper用于操作房间库存
    private final RoomMapper roomMapper = new RoomMapperImpl();
    // 添加消息服务
    private final IMessageService messageService = new MessageServiceImpl();

    /**
     * 获取用户所有订单
     *
     * @param userId 用户ID
     * @return 订单列表
     */
    @Override
    public List<Order> getUserOrders(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        return orderMapper.selectUserOrders(userId);
    }

    /**
     * 获取所有订单
     *
     * @return 订单列表
     */
    @Override
    public List<Order> getAllOrders() {
        return orderMapper.selectAllOrders();
    }

    /**
     * 根据酒店名称获取订单
     *
     * @param hotelName 酒店名称
     * @return 订单列表
     */
    @Override
    public List<Order> getOrdersByHotel(String hotelName) {
        if (hotelName == null || hotelName.trim().isEmpty()) {
            throw new BusinessException("酒店名称不能为空");
        }
        return orderMapper.selectOrdersByHotel(hotelName);
    }

    /**
     * 创建订单（自动生成自增ID和创建时间）
     *
     * @param userId    用户ID
     * @param hotelName 酒店名称
     * @param roomType  房型
     * @return 创建成功的订单对象（包含自动生成的ID和系统时间）
     */
    @Override
    public Order createOrder(String userId, String hotelName, String roomType) {
        // 1. 校验核心参数
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        if (hotelName == null || hotelName.trim().isEmpty()) {
            throw new BusinessException("酒店名称不能为空");
        }
        if (roomType == null || roomType.trim().isEmpty()) {
            throw new BusinessException("房型不能为空");
        }

        // 2. 校验房间是否存在且库存充足（新增逻辑）
        Room room = roomMapper.selectRoomByTypeAndHotel(roomType, hotelName);
        if (room == null) {
            throw new BusinessException("该酒店不存在此房型：" + roomType);
        }

//        // 打印room对象的所有属性（关键排查代码）
//        System.out.println("===== 房间信息打印 =====");
//        System.out.println("roomType: " + room.getRoomType());
//        System.out.println("hotelName: " + room.getHotelName());
//        System.out.println("imageUrl: " + room.getImageUrl());
//        System.out.println("price: " + room.getPrice());
//        System.out.println("availableCount: " + room.getAvailableCount()); // 重点关注这个值
//        System.out.println("breakfast: " + room.getBreakfast());
//        System.out.println("=======================");

        if (room.getAvailableCount() == null || room.getAvailableCount() <= 0) {
            throw new BusinessException("房型【" + roomType + "】当前无可用房间");
        }

        // 3. 先减少房间库存（核心关联逻辑：每个订单对应1个房间）
        boolean decreaseSuccess = roomMapper.decreaseAvailableCountByOne(roomType, hotelName);
        if (!decreaseSuccess) {
            throw new BusinessException("创建订单失败，房间库存不足");
        }

        // 4. 生成订单信息并插入数据库
        Order order = new Order();
        order.setUserId(userId);
        order.setHotelName(hotelName);
        order.setRoomType(roomType);
        order.setCreateTime(new Date());
        order.setPayTime(null);
        order.setCancelTime(null);
        
        // 设置订单金额为房间价格
        order.setAmount(room.getPrice());

        orderMapper.insertOrderAndReturnId(order);

        // 5. 发送订单创建消息通知
        try {
            Message message = new Message();
            message.setUserId(userId);
            message.setTitle("订单创建通知");
            message.setContent("您的订单#" + order.getId() + "已成功创建，酒店：" + hotelName + "，房型：" + roomType + "。请及时支付。");
            message.setType("order_update");
            message.setRelatedId(String.valueOf(order.getId()));
            message.setIsRead(false);
            message.setCreateTime(new Date());
            
            messageService.addMessage(message);
        } catch (Exception e) {
            // 记录日志但不影响主流程
            System.err.println("[OrderServiceImpl.createOrder] 发送消息通知失败: " + e.getMessage());
        }

        return order;
    }

    /**
     * 支付订单
     *
     * @param orderId       订单ID
     * @param paymentMethod 支付方式
     */
    @Override
    public void payOrder(String orderId, String paymentMethod) {
        // 参数校验
        if (orderId == null || orderId.trim().isEmpty()) {
            throw new BusinessException("订单ID不能为空");
        }
        if (paymentMethod == null || paymentMethod.trim().isEmpty()) {
            throw new BusinessException("支付方式不能为空");
        }

        // 解析订单ID
        Integer id;
        try {
            id = Integer.parseInt(orderId);
        } catch (NumberFormatException e) {
            throw new BusinessException("订单ID格式错误");
        }
        
        // 获取订单信息
        Order order = orderMapper.selectOrderById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        // 检查订单是否已支付
        if (order.getPayTime() != null) {
            throw new BusinessException("订单已支付，不能重复支付");
        }
        
        // 检查订单是否已取消
        if (order.getCancelTime() != null) {
            throw new BusinessException("订单已取消，不能支付");
        }
        
        // 根据订单中的房型和酒店名称查询对应的房间价格
        Room room = roomMapper.selectRoomByTypeAndHotel(order.getRoomType(), order.getHotelName());
        if (room == null) {
            throw new BusinessException("无法获取房间价格信息，支付失败");
        }
        
        BigDecimal amount = room.getPrice();
        if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException("房间价格信息无效，支付失败");
        }

        // 自动生成支付时间（当前系统时间）
        Date payTime = new Date();

        // 执行支付更新操作
        int rows = orderMapper.updateOrderForPayment(id, paymentMethod, amount, payTime);
        if (rows == 0) {
            throw new BusinessException("订单支付失败，可能原因：订单不存在或已支付/取消");
        }
        
        // 发送订单支付成功消息通知
        try {
            Message message = new Message();
            message.setUserId(order.getUserId());
            message.setTitle("订单支付成功");
            message.setContent("您的订单#" + orderId + "已支付成功，金额：" + amount + "，支付方式：" + paymentMethod + "。");
            message.setType("order_update");
            message.setRelatedId(orderId);
            message.setIsRead(false);
            message.setCreateTime(new Date());
            
            messageService.addMessage(message);
        } catch (Exception e) {
            // 记录日志但不影响主流程
            System.err.println("[OrderServiceImpl.payOrder] 发送消息通知失败: " + e.getMessage());
        }
    }

    /**
     * 取消订单
     *
     * @param orderId 订单ID
     */
    @Override
    public void cancelOrder(String orderId) {
        // 1. 参数校验
        if (orderId == null || orderId.trim().isEmpty()) {
            throw new BusinessException("订单ID不能为空");
        }

        // 2. 解析订单ID
        Integer id;
        try {
            id = Integer.parseInt(orderId);
        } catch (NumberFormatException e) {
            throw new BusinessException("订单ID格式错误");
        }
        
        // 3. 获取订单详情，确保有房型和酒店名称信息
        Order order = orderMapper.selectOrderById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        // 添加调试日志
        System.out.println("===== 订单信息调试 =====");
        System.out.println("订单ID: " + order.getId());
        System.out.println("用户ID: " + order.getUserId());
        System.out.println("酒店名称: " + order.getHotelName());
        System.out.println("房型: " + order.getRoomType());
        System.out.println("创建时间: " + order.getCreateTime());
        System.out.println("支付时间: " + order.getPayTime());
        System.out.println("取消时间: " + order.getCancelTime());
        System.out.println("金额: " + order.getAmount());
        System.out.println("支付方式: " + order.getPaymentMethod());
        System.out.println("=======================");
        
        // 4. 校验订单状态（未支付的订单才能取消）
        if (order.getPayTime() != null) {
            throw new BusinessException("已支付订单无法取消");
        }
        if (order.getCancelTime() != null) {
            throw new BusinessException("订单已取消，无需重复操作");
        }
        
        // 5. 检查房型和酒店名是否存在
        String roomType = order.getRoomType();
        String hotelName = order.getHotelName();
        if (roomType == null || roomType.trim().isEmpty() || hotelName == null || hotelName.trim().isEmpty()) {
            throw new BusinessException("订单信息不完整，无法恢复房间库存");
        }
        
        // 6. 设置订单取消时间
        Date cancelTime = new Date();
        order.setCancelTime(cancelTime);
        
        // 7. 更新订单状态
        boolean updateSuccess = orderMapper.updateOrder(order);
        if (!updateSuccess) {
            throw new BusinessException("订单取消失败");
        }
        
        // 8. 恢复房间库存（重要关联逻辑）
        boolean increaseSuccess = roomMapper.increaseAvailableCountByOne(roomType, hotelName);
        if (!increaseSuccess) {
            throw new BusinessException("房间库存恢复失败，请联系管理员");
        }
        
        // 9. 发送订单取消消息通知
        try {
            Message message = new Message();
            message.setUserId(order.getUserId());
            message.setTitle("订单已取消");
            message.setContent("您的订单#" + orderId + "已成功取消。酒店：" + hotelName + "，房型：" + roomType + "。");
            message.setType("order_update");
            message.setRelatedId(orderId);
            message.setIsRead(false);
            message.setCreateTime(new Date());
            
            messageService.addMessage(message);
        } catch (Exception e) {
            // 记录日志但不影响主流程
            System.err.println("[OrderServiceImpl.cancelOrder] 发送消息通知失败: " + e.getMessage());
        }
    }
    
    /**
     * 办理退房
     * 
     * @param orderId 订单ID
     */
    @Override
    public void checkoutOrder(String orderId) {
        // 1. 参数校验
        if (orderId == null || orderId.trim().isEmpty()) {
            throw new BusinessException("订单ID不能为空");
        }

        // 2. 解析订单ID
        Integer id;
        try {
            id = Integer.parseInt(orderId);
        } catch (NumberFormatException e) {
            throw new BusinessException("订单ID格式错误");
        }
        
        // 3. 获取订单详情
        Order order = orderMapper.selectOrderById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        // 4. 校验订单状态（已支付、未取消、未退房的订单才能退房）
        if (order.getPayTime() == null) {
            throw new BusinessException("未支付订单无法办理退房");
        }
        if (order.getCancelTime() != null) {
            throw new BusinessException("已取消订单无法办理退房");
        }
        if (order.getCheckoutTime() != null) {
            throw new BusinessException("该订单已办理退房，无需重复操作");
        }
        
        // 5. 设置退房时间
        Date checkoutTime = new Date();
        order.setCheckoutTime(checkoutTime);
        
        // 6. 更新订单状态
        boolean updateSuccess = orderMapper.updateOrder(order);
        if (!updateSuccess) {
            throw new BusinessException("办理退房失败");
        }
        
        // 7. 恢复房间库存
        String roomType = order.getRoomType();
        String hotelName = order.getHotelName();
        boolean increaseSuccess = roomMapper.increaseAvailableCountByOne(roomType, hotelName);
        if (!increaseSuccess) {
            throw new BusinessException("房间库存恢复失败，请联系管理员");
        }
        
        // 8. 发送退房成功消息通知
        try {
            Message message = new Message();
            message.setUserId(order.getUserId());
            message.setTitle("退房成功通知");
            message.setContent("您的订单#" + orderId + "已成功办理退房。感谢您选择" + hotelName + "，欢迎下次光临！");
            message.setType("order_update");
            message.setRelatedId(orderId);
            message.setIsRead(false);
            message.setCreateTime(new Date());
            
            messageService.addMessage(message);
        } catch (Exception e) {
            // 记录日志但不影响主流程
            System.err.println("[OrderServiceImpl.checkoutOrder] 发送消息通知失败: " + e.getMessage());
        }
    }

    @Override
    public Order getOrderById(String orderId) {
        if (orderId == null || orderId.trim().isEmpty()) {
            throw new BusinessException("订单ID不能为空");
        }
        Integer id;
        try {
            id = Integer.parseInt(orderId);
        } catch (NumberFormatException e) {
            throw new BusinessException("订单ID格式错误");
        }
        return orderMapper.selectOrderById(id);
    }

    @Override
    public boolean updateOrder(Order order) {
        if (order == null || order.getId() == null) {
            throw new BusinessException("订单信息不完整");
        }
        // 可加更多校验
        return orderMapper.updateOrder(order);
    }

    @Override
    public boolean deleteOrder(String orderId) {
        if (orderId == null || orderId.trim().isEmpty()) {
            throw new BusinessException("订单ID不能为空");
        }
        Integer id;
        try {
            id = Integer.parseInt(orderId);
        } catch (NumberFormatException e) {
            throw new BusinessException("订单ID格式错误");
        }
        return orderMapper.deleteOrder(id);
    }
}